package com.fingard.dsp.bank.directbank.abc02;

import com.fingard.client.DspClient;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.helpers.FileType;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.TcpReceiver;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class ABC02Transaction extends ABC02Base implements ITransaction {

    //采用流处理方式
    //1、循环调用readRecord()读取一个请求明细，然后写入发银行的XML对象
    //2、发银行
    //3、循环调用XmlTextReader.read()读取一个银行返回节点，赋值返回ATS的明细对象，
    //   然后调用writeRetDetail()，写入返回ATS的明细
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        if ("3".equals(p_req7516.actBankType)) {
            return qrySubAcctTrans(p_req7516);
        }
        //历史明细查询返回ATS的对象
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            ABC02Header bankHeader = new ABC02Header();
            bankHeader.CCTransCode = "CQRA10";//交易代码
            bankHeader.ReqSeqNo = p_req7516.reqHeader.transSeqID;
            //Date tmpDateFrom = p_req7516.getDateFrom();
            //Date tmpDateTo = p_req7516.getDateTo();

            //tmpClndrStepTo.get(Calendar.MONTH) MONTH是从0开始编的，意味着0是1月，11是12月
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            //按自然月循环查询
            while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //判断是否跨月
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    //跨月则设置为月末
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }


                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                //写入通用的头部节点
                writeCommonHeader(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("Corp");
                xmlWriter.writeElementString("StartDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                xmlWriter.writeElementString("EndDate", Format.Date8Format.format(tmpClndrStepTo.getTime()));
                xmlWriter.writeEndElement();

                xmlWriter.writeStartElement("Channel");
                xmlWriter.writeElementString("LastJrnNo", "0");
                xmlWriter.writeEndElement();

                xmlWriter.writeStartElement("Cmp");
                xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_req7516.actNum));
                String dbProv = p_req7516.actArea;
                if ("true".equals(getBankConfig().getValueAsString("useActInfoSetOwnerArea").toLowerCase())) {
                    if ((p_req7516.actNum.indexOf('-') > 0 && p_req7516.actNum.length() == 18) || (p_req7516.actNum.length() == 17)) {
                        dbProv = p_req7516.actNum.substring(0, 2);
                    }
                }
                xmlWriter.writeElementString("DbProv", dbProv);
                xmlWriter.writeElementString("DbCur", convertCurToBank(p_req7516.actCur));
                xmlWriter.writeElementClosed("StartTime");
                xmlWriter.writeEndElement();

                xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

                XmlTextReader tmpBkReader;
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                            int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                            if (tmpRecordNum > 0) {
                                String tmpDataMFS = null;
                                String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                                if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                                    String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                    String tmpFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + tmpBatchFileName;

                                    if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                        WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                        DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                        dspClient.charsetName = getCharset();
                                        TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                        if (tcpRec.isCompleted) {
                                            if (tcpRec.isRtnBinaryFile) {
                                                tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                            } else {
                                                String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                                WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                            }
                                        } else {
                                            this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                        }
                                    } else if ("ftp".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        tmpFilePath = getTempFileDirectory() + File.separator + tmpBatchFileName;

                                        WriteBankLogLn2("结果文件保存本机路径: " + tmpFilePath);
                                        FtpSet ftpSet = bankFront.getFtpSet("");
                                        WriteBankLogLn2("ftp服务器待下载文件路径: " + ftpSet.downDir + "/" + tmpBatchFileName);
                                        FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
                                        FtpReceiver ftpReceiver = ftpPortClient.downloadFile(tmpBatchFileName, tmpFilePath);
                                        if (ftpReceiver.isCompleted) {
                                            tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                            WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);
                                        } else {
                                            tmpRespCode = "-1";
                                            tmpRespInfo = "文件下载失败" + ftpReceiver.connMsg;
                                            WriteBankLogLn2("文件下载失败" + ftpReceiver.connMsg);
                                        }
                                    } else {
                                        this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                        tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                    }

                                    if (tmpDataMFS == null) {
                                        this.WriteBankLogLn("读取前置数据文件返回为null，需确认前置文件夹配置和文件是否存在");
                                    } else {
                                        this.WriteBankLogStep3(tmpDataMFS);
                                    }
                                } else {
                                    tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");//
                                }
                                if (tmpDataMFS != null) {
                                    StringBuilder tmpSbLog = new StringBuilder();
                                    ArrayList<String[]> tmpArrayList = MFSHelper.getTextArray(tmpDataMFS, "|", tmpFieldNum, tmpRecordNum, tmpSbLog);
                                    if (tmpSbLog.length() == 0) {
                                        /*
                                    0省市代码|1账号|2货币码|3交易日期|4交易时间|5日志号|6交易类型|7交易行号|8户名|9发生额标志|
									10对方账号省市代码|11对方账号|12对方账号货币码|13对方账号户名|14对方账号开户行|15现转标志|16错账日期|17错账传票号|
									18交易金额|19账户余额|20上笔余额|21手续费总额|22凭证种类|23凭证省市代号|24凭证批次号|25凭证号|26客户参考号|27交易码|
									28柜员号|29传票号|30摘要|31附言|32交易来源|
										 * */
                                        boolean pickupUsage7516 = this.getBankConfig().getValueAsBool("pickupUsage7516");
                                        for (int i = 0; i < tmpArrayList.size(); i++) {

                                            String[] tmpEachArr = tmpArrayList.get(i);
                                            //发生额标志(21) 0正常  1红字  2蓝字 3已抹 4抹帐
                                            if (tmpEachArr[9].equals("0") || tmpEachArr[9].equals("1") || tmpEachArr[9].equals("2")) {
                                                RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                                tmpRetDetail.actArea = tmpEachArr[0].trim();
                                                tmpRetDetail.actNum = tmpEachArr[1].trim();
                                                tmpRetDetail.cur = this.convertCurToATS(tmpEachArr[2]).trim();

                                                String tmpRecBank = StringHelper.convertToDBC(tmpEachArr[14]).trim();
                                                tmpRetDetail.recAccBank = tmpRecBank;

                                                boolean jionBkArea7516 = getBankConfig().getValueAsBool("jionBkArea7516");
                                                if (tmpRecBank.contains("中国农业银行") && jionBkArea7516 && StringHelper.hasAnyChar(tmpEachArr[10])) {
                                                    tmpRetDetail.recAccNum = tmpEachArr[10].trim() + tmpEachArr[11].trim();
                                                } else {
                                                    tmpRetDetail.recAccNum = tmpEachArr[11].trim();
                                                }
                                                tmpRetDetail.recAccName = tmpEachArr[13].trim();
                                                if (tmpEachArr[18].startsWith("-")) {
                                                    tmpRetDetail.cdFlag = "1";
                                                    if (tmpEachArr[9].equals("1") || tmpEachArr[9].equals("2")) {
                                                        tmpRetDetail.cdFlag = "2";
                                                    }
                                                } else {
                                                    tmpRetDetail.cdFlag = "2";
                                                    if (tmpEachArr[9].equals("1") || tmpEachArr[9].equals("2")) {
                                                        tmpRetDetail.cdFlag = "1";
                                                    }
                                                }
                                                tmpRetDetail.tranAmt = tmpEachArr[18].replace("-", "").trim();
                                                if (tmpEachArr[3].length() == 8) {
                                                    tmpRetDetail.tranDate = tmpEachArr[3].substring(0, 4) + "-" + tmpEachArr[3].substring(4, 6) + "-" + tmpEachArr[3].substring(6, 8);
                                                } else {
                                                    tmpRetDetail.tranDate = tmpEachArr[3];
                                                }
                                                if (tmpEachArr[4].length() >= 14) {
                                                    tmpRetDetail.tranTime = tmpEachArr[4].substring(0, 4) + "-" + tmpEachArr[4].substring(4, 6) + "-" + tmpEachArr[4].substring(6, 8) + " " + tmpEachArr[4].substring(8, 10) + ":" + tmpEachArr[4].substring(10, 12) + ":" + tmpEachArr[4].substring(12, 14);
                                                } else {
                                                    tmpRetDetail.tranTime = tmpEachArr[4];
                                                }
                                                tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                                tmpRetDetail.postTimestamp = tmpEachArr[4].trim();
                                                tmpRetDetail.accBal = tmpEachArr[19].trim();
                                                tmpRetDetail.billType = tmpEachArr[22].trim();
                                                tmpRetDetail.billNum = tmpEachArr[29].trim();
                                                String tmpAbstr = StringHelper.convertToDBC(tmpEachArr[31].trim());
                                                tmpRetDetail.usage = "false".equalsIgnoreCase(getBankConfig().getValueAsString("TransUsageConvertToDBC")) ? tmpEachArr[31] : tmpAbstr;
//                                                tmpRetDetail.usage = tmpEachArr[30];
                                                if (pickupUsage7516) {
                                                    if (StringHelper.hasAnyChar(tmpRetDetail.usage) && tmpRetDetail.usage.indexOf(";") > 0) {
                                                        //<Usage>20190423;20190423</Usage>
                                                        String[] spVals = tmpRetDetail.usage.split(";");
                                                        if (spVals.length > 1 && StringHelper.hasAnyChar(spVals[spVals.length - 1])) {
                                                            tmpRetDetail.usage = spVals[spVals.length - 1];
                                                        }
                                                    }
                                                }
                                                tmpRetDetail.abstr = pickupAbstr(tmpAbstr);

                                                String comment = tmpEachArr[30];
                                                boolean useNewComment = getBankConfig().getValueAsBool("useNewComment");
                                                WriteBankLogLn("useNewComment:" + useNewComment);
                                                if (useNewComment) {
                                                    comment = getBankConfig().getMapValueByKey("commentMapping",comment);
                                                }
                                                tmpRetDetail.comment = comment;
                                                tmpRetDetail.originator = tmpEachArr[5].trim();//和回单进行匹配
                                                tmpRetDetail.payCode = StringHelper.joinNotEmpty("+", tmpEachArr[27], tmpEachArr[25], tmpEachArr[26]);
                                                if (getBankConfig().getValueAsBool("fixPayCode")) {
                                                    tmpRetDetail.payCode = tmpEachArr[5];
                                                }
                                                //8位日期_本方账号_日志号_对方账号
                                                tmpRetDetail.busRef = tmpEachArr[4].replaceAll("-","")+tmpEachArr[1]+tmpEachArr[6]+tmpEachArr[11];
                                                tmpRetDetail.receiptNo = tmpEachArr[5].trim();//日志号,暂定用日志号作为回单编号回传，与电子回单中日志号做匹配处理

                                                nodeAnalysic(tmpEachArr, tmpRetDetail, getCharset());
                                                retAts.writeRetDetail(tmpRetDetail);
                                            }
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = tmpSbLog.toString();
                                    }
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "数据为空";
                                }
                            }
                        } else if (!"查询无数据!".equals(tmpRetRxtInfo)) {
                            tmpRespCode = "-1";
                            if (!StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                                tmpRespInfo = tmpRetRxtInfo;
                            } else {
                                tmpRespInfo = tmpRetInfo;
                            }
                            break;
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSbMsg.toString();
                        break;
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                    break;
                }

                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    //当日明细查询调用历史明细查询方法
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        //通用b2e0035
        Req7516HisTrans tmpReq7516 = new Req7516HisTrans(p_req7515.reqHeader);
        tmpReq7516.actArea = p_req7515.actArea;
        tmpReq7516.actCur = p_req7515.actCur;
        tmpReq7516.actNum = p_req7515.actNum;
        tmpReq7516.higherLevelAct = p_req7515.higherLevelAct;
        tmpReq7516.actBankType = p_req7515.actBankType;
        String tmpStrToday = Format.Date8Format.format(new Date());
        tmpReq7516.dateFrom = tmpStrToday;
        tmpReq7516.dateTo = tmpStrToday;
        return d_7516_HisTrans(tmpReq7516);
    }

    private RetAtsTrans qrySubAcctTrans_CQRA14(Req7516HisTrans p_req7516) throws Exception {
        //历史明细查询返回ATS的对象
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            ABC02Header bankHeader = new ABC02Header();
            bankHeader.CCTransCode = "CQRA14";//交易代码
            bankHeader.ReqSeqNo = p_req7516.reqHeader.transSeqID;
            //Date tmpDateFrom = p_req7516.getDateFrom();
            //Date tmpDateTo = p_req7516.getDateTo();

            //tmpClndrStepTo.get(Calendar.MONTH) MONTH是从0开始编的，意味着0是1月，11是12月
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;

            boolean isSubAcct = StringHelper.hasAnyChar(p_req7516.higherLevelAct);
            //按自然月循环查询
            while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //判断是否跨月
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    //跨月则设置为月末
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }


                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                //写入通用的头部节点
                writeCommonHeader(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("Corp");
                xmlWriter.writeElementString("StartDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                xmlWriter.writeElementString("EndDate", Format.Date8Format.format(tmpClndrStepTo.getTime()));
                xmlWriter.writeEndElement();

                xmlWriter.writeStartElement("Cmp");
                String dbProv = p_req7516.actArea;
                if ("true".equals(getBankConfig().getValueAsString("useActInfoSetOwnerArea").toLowerCase())) {
                    if ((p_req7516.actNum.indexOf('-') > 0 && p_req7516.actNum.length() == 18) || (p_req7516.actNum.length() == 17)) {
                        dbProv = p_req7516.actNum.substring(0, 2);
                    }
                }
                xmlWriter.writeElementString("DbProv", dbProv);
                xmlWriter.writeElementString("DbCur", convertCurToBank(p_req7516.actCur));
                if (!isSubAcct) {
                    xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_req7516.actNum));//借方账号
                    xmlWriter.writeElementString("DbLogAccNo", "0000000000");//起始多级账簿号
                    xmlWriter.writeElementString("CrLogAccNo", "0000000000");//终止多级账簿号
                } else {
                    xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_req7516.higherLevelAct));//借方账号
                    xmlWriter.writeElementString("DbLogAccNo", p_req7516.actNum);//起始多级账簿号
                    xmlWriter.writeElementString("CrLogAccNo", p_req7516.actNum);//终止多级账簿号
                }
                xmlWriter.writeEndElement();

                xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

                XmlTextReader tmpBkReader;
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                            int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                            if (tmpRecordNum > 0) {
                                String tmpDataMFS = null;
                                String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                                if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                                    String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                    String tmpFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + tmpBatchFileName;

                                    if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                        WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                        DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                        dspClient.charsetName = getCharset();
                                        TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                        if (tcpRec.isCompleted) {
                                            if (tcpRec.isRtnBinaryFile) {
                                                tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                            } else {
                                                String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                                WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                            }
                                        } else {
                                            this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                        }
                                    } else if ("ftp".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        tmpFilePath = getTempFileDirectory() + File.separator + tmpBatchFileName;

                                        WriteBankLogLn2("结果文件保存本机路径: " + tmpFilePath);
                                        FtpSet ftpSet = bankFront.getFtpSet("");
                                        WriteBankLogLn2("ftp服务器待下载文件路径: " + ftpSet.downDir + "/" + tmpBatchFileName);
                                        FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
                                        FtpReceiver ftpReceiver = ftpPortClient.downloadFile(tmpBatchFileName, tmpFilePath);
                                        if (ftpReceiver.isCompleted) {
                                            tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                            WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);
                                        } else {
                                            tmpRespCode = "-1";
                                            tmpRespInfo = "文件下载失败" + ftpReceiver.connMsg;
                                            WriteBankLogLn2("文件下载失败" + ftpReceiver.connMsg);
                                        }
                                    } else {
                                        this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                        tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                    }

                                    if (tmpDataMFS == null) {
                                        this.WriteBankLogLn("读取前置数据文件返回为null，需确认前置文件夹配置和文件是否存在");
                                    } else {
                                        this.WriteBankLogStep3(tmpDataMFS);
                                    }
                                } else {
                                    tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");//
                                }
                                if (tmpDataMFS != null) {
                                    StringBuilder tmpSbLog = new StringBuilder();
                                    ArrayList<String[]> tmpArrayList = MFSHelper.getTextArray(tmpDataMFS, "|", tmpFieldNum, tmpRecordNum, tmpSbLog);
                                    if (tmpSbLog.length() == 0) {
                                        /*
                                        0省市代码|1账号|2多级账簿号|3货币码|4交易日期|5日志号|6交易时间|7账号名称|8账簿名称|9交易类型|
                                        10交易行号|11传票号|12红蓝字标志|13现转标志|14金额|15余额|16上笔余额|17凭证种类|18交易码|19凭证号码|
                                        20对方省市代码|21对方账号|22对方币种|23对方户名|24对方行名|25错误日期|26错误传票号|27错误传票号|28摘要|29备注|
										 * */
                                        for (int i = 0; i < tmpArrayList.size(); i++) {
                                            String[] tmpEachArr = tmpArrayList.get(i);
                                            boolean needDoNext = false;
                                            //1.查询账号为多级账簿子账号时，银行返回账号需等于上级账号且银行返回多级账簿号等于查询账号
                                            //2.查询账号为多级账簿主账号时，银行返回账号需等于查询账号且银行返回多级账簿号等于0000000000
                                            if (!((isSubAcct && p_req7516.actNum.equals(tmpEachArr[2]) && p_req7516.higherLevelAct.equals(tmpEachArr[1])) || (!isSubAcct && p_req7516.actNum.equals(tmpEachArr[1]) && "0000000000".equals(tmpEachArr[2])))) {
                                                needDoNext = true;
                                            }
                                            if (needDoNext) {
                                                continue;
                                            }
                                            RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                            tmpRetDetail.actArea = p_req7516.actArea;

                                            tmpRetDetail.actNum = isSubAcct ? tmpEachArr[2] : tmpEachArr[1];
                                            tmpRetDetail.cur = this.convertCurToATS(tmpEachArr[3]);

                                            String tmpRecBank = StringHelper.convertToDBC(tmpEachArr[24]).trim();
                                            tmpRetDetail.recAccBank = tmpRecBank;

                                            boolean jionBkArea7516 = getBankConfig().getValueAsBool("jionBkArea7516");
                                            if (tmpRecBank.contains("中国农业银行") && jionBkArea7516 && StringHelper.hasAnyChar(tmpEachArr[20])) {
                                                tmpRetDetail.recAccNum = tmpEachArr[20].trim() + tmpEachArr[21].trim();
                                            } else {
                                                tmpRetDetail.recAccNum = tmpEachArr[21].trim();
                                            }
                                            tmpRetDetail.recAccName = tmpEachArr[23].trim();
                                            if (tmpEachArr[14].startsWith("-")) {
                                                tmpRetDetail.cdFlag = "1";
                                            } else {
                                                tmpRetDetail.cdFlag = "2";
                                            }
                                            tmpRetDetail.tranAmt = tmpEachArr[14].replace("-", "");
                                            if (tmpEachArr[4].length() == 8) {
                                                tmpRetDetail.tranDate = tmpEachArr[4].substring(0, 4) + "-" + tmpEachArr[4].substring(4, 6) + "-" + tmpEachArr[4].substring(6, 8);
                                            } else {
                                                tmpRetDetail.tranDate = tmpEachArr[4];
                                            }
                                            if (tmpEachArr[6].length() >= 14) {
                                                tmpRetDetail.tranTime = tmpEachArr[6].substring(0, 4) + "-" + tmpEachArr[6].substring(4, 6) + "-" + tmpEachArr[6].substring(6, 8) + " " + tmpEachArr[6].substring(8, 10) + ":" + tmpEachArr[6].substring(10, 12) + ":" + tmpEachArr[6].substring(12, 14);
                                            } else {
                                                tmpRetDetail.tranTime = tmpEachArr[6];
                                            }
                                            tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                            tmpRetDetail.postTimestamp = tmpEachArr[6];
                                            tmpRetDetail.accBal = tmpEachArr[15];
                                            tmpRetDetail.billType = tmpEachArr[17];
                                            tmpRetDetail.billNum = tmpEachArr[19];
                                            String tmpAbstr = StringHelper.convertToDBC(tmpEachArr[28]);
                                            tmpRetDetail.usage = "false".equalsIgnoreCase(getBankConfig().getValueAsString("TransUsageConvertToDBC")) ? tmpEachArr[28] : tmpAbstr;
                                            if (StringHelper.hasAnyChar(tmpRetDetail.usage) && tmpRetDetail.usage.indexOf(";") > 0) {
                                                //<Usage>20190423;20190423</Usage>
                                                String[] spVals = tmpRetDetail.usage.split(";");
                                                if (spVals.length == 2 && spVals[0].equals(spVals[1])) {
                                                    tmpRetDetail.usage = spVals[0];
                                                }
                                            }
                                            tmpRetDetail.abstr = pickupAbstr(tmpAbstr);
                                            //tmpRetDetail.comment = tmpEachArr[29];//tmpEachArr[32];
                                            tmpRetDetail.originator = tmpEachArr[5];
                                            tmpRetDetail.payCode = StringHelper.joinNotEmpty("+", tmpEachArr[29]);
                                            nodeAnalysic(tmpEachArr, tmpRetDetail, getCharset());
                                            retAts.writeRetDetail(tmpRetDetail);
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = tmpSbLog.toString();
                                    }
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "数据为空";
                                }
                            }
                        } else if (!"查询无数据!".equals(tmpRetRxtInfo)) {
                            tmpRespCode = "-1";
                            if (!StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                                tmpRespInfo = tmpRetRxtInfo;
                            } else {
                                tmpRespInfo = tmpRetInfo;
                            }
                            break;
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSbMsg.toString();
                        break;
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                    break;
                }

                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    private RetAtsTrans qrySubAcctTrans_CQRD01(Req7516HisTrans p_req7516) throws Exception {
        //历史明细查询返回ATS的对象
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            ABC02Header bankHeader = new ABC02Header();
            bankHeader.CCTransCode = "CQRD01";//交易代码
            bankHeader.ReqSeqNo = p_req7516.reqHeader.transSeqID;

            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;

            boolean isSubAcct = StringHelper.hasAnyChar(p_req7516.higherLevelAct);
            //按自然月循环查询
            while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //判断是否跨月
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    //跨月则设置为月末
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }

                boolean isContinue = true;
                String contFlag = "";
                String contLast = "";
                while (isContinue && tmpRespCode.length() == 0) {

                    XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                    //写入通用的头部节点
                    writeCommonHeader(xmlWriter, bankHeader);

                    xmlWriter.writeStartElement("Cmp");
                    String dbProv = p_req7516.actArea;
                    if ("true".equals(getBankConfig().getValueAsString("useActInfoSetOwnerArea").toLowerCase())) {
                        if ((p_req7516.actNum.indexOf('-') > 0 && p_req7516.actNum.length() == 18) || (p_req7516.actNum.length() == 17)) {
                            dbProv = p_req7516.actNum.substring(0, 2);
                        }
                    }
                    xmlWriter.writeElementString("DbProv", dbProv);
                    xmlWriter.writeElementString("DbCur", convertCurToBank(p_req7516.actCur));
                    if (!isSubAcct) {
                        xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_req7516.actNum));//借方账号
                        xmlWriter.writeElementString("DbLogAccNo", "0000000000");//起始多级账簿号
                        xmlWriter.writeElementString("CrLogAccNo", "0000000000");//终止多级账簿号
                    } else {
                        xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_req7516.higherLevelAct));//借方账号
                        xmlWriter.writeElementString("DbLogAccNo", p_req7516.actNum);//起始多级账簿号
                        xmlWriter.writeElementString("CrLogAccNo", p_req7516.actNum);//终止多级账簿号
                    }
                    xmlWriter.writeEndElement();

                    xmlWriter.writeStartElement("Corp");
                    xmlWriter.writeElementString("StartDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    xmlWriter.writeElementString("EndDate", Format.Date8Format.format(tmpClndrStepTo.getTime()));
                    xmlWriter.writeEndElement();

                    xmlWriter.writeStartElement("Cme");
                    xmlWriter.writeElementString("ContLast", contLast);//续查条件
                    xmlWriter.writeEndElement();
                    xmlWriter.writeEndDocument();

                    String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

                    XmlTextReader tmpBkReader;
                    if (tmpStrRet[0].length() == 0) {
                        StringBuilder tmpSbMsg = new StringBuilder();
                        tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                            String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                            String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                            if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                                contFlag = tmpBkReader.getFirstText("/ap/Cmp/ContFlag");
                                if ("0".equals(contFlag)) {
                                    isContinue = false;
                                }
                                contLast = tmpBkReader.getFirstText("/ap/Cme/ContLast");

                                int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                                int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                                if (tmpRecordNum > 0) {
                                    String tmpDataMFS = null;
                                    String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                                    if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                                        String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                        String tmpFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + tmpBatchFileName;

                                        if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                            this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                            WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                            DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                            dspClient.charsetName = getCharset();
                                            TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                            if (tcpRec.isCompleted) {
                                                if (tcpRec.isRtnBinaryFile) {
                                                    tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                                } else {
                                                    String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                                    WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                                }
                                            } else {
                                                this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                            }
                                        } else if ("ftp".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                            tmpFilePath = getTempFileDirectory() + File.separator + tmpBatchFileName;

                                            WriteBankLogLn2("结果文件保存本机路径: " + tmpFilePath);
                                            FtpSet ftpSet = bankFront.getFtpSet("");
                                            WriteBankLogLn2("ftp服务器待下载文件路径: " + ftpSet.downDir + "/" + tmpBatchFileName);
                                            FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
                                            FtpReceiver ftpReceiver = ftpPortClient.downloadFile(tmpBatchFileName, tmpFilePath);
                                            if (ftpReceiver.isCompleted) {
                                                tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                                WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);
                                            } else {
                                                tmpRespCode = "-1";
                                                tmpRespInfo = "文件下载失败" + ftpReceiver.connMsg;
                                                WriteBankLogLn2("文件下载失败" + ftpReceiver.connMsg);
                                            }
                                        } else {
                                            this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                            tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                        }

                                        if (tmpDataMFS == null) {
                                            this.WriteBankLogLn("读取前置数据文件返回为null，需确认前置文件夹配置和文件是否存在");
                                        } else {
                                            this.WriteBankLogStep3(tmpDataMFS);
                                        }
                                    } else {
                                        tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");//
                                    }
                                    if (tmpDataMFS != null) {
                                        StringBuilder tmpSbLog = new StringBuilder();
                                        ArrayList<String[]> tmpArrayList = MFSHelper.getTextArray(tmpDataMFS, "|", tmpFieldNum, tmpRecordNum, tmpSbLog);
                                        if (tmpSbLog.length() == 0) {
                                        /*
                                        0省市代码|1账号|2账薄号|3货币码|4交易日期|5日志号|6交易时间|7户名|8账薄名|9交易类型|10交易行号|11传票号|12发生额标识|13现转标志|14交易金额|15账户余额|16上笔余额|17凭证种类|18交易码|19凭证号|20对方账号省市代码|21对方账号|22对方账号货币码|23对方账号户名|24对方账号开户行|25错账日期|26错账传票号|27记账柜员|28摘要|29附言|30红蓝字标识|31备注1|32备注2|
										 * */
                                            for (int i = 0; i < tmpArrayList.size(); i++) {
                                                String[] tmpEachArr = tmpArrayList.get(i);
                                                boolean needDoNext = false;
                                                //1.查询账号为多级账簿子账号时，银行返回账号需等于上级账号且银行返回多级账簿号等于查询账号
                                                //2.查询账号为多级账簿主账号时，银行返回账号需等于查询账号且银行返回多级账簿号等于0000000000
                                                if (!((isSubAcct && p_req7516.actNum.equals(tmpEachArr[2]) && p_req7516.higherLevelAct.equals(tmpEachArr[1])) || (!isSubAcct && p_req7516.actNum.equals(tmpEachArr[1]) && "0000000000".equals(tmpEachArr[2])))) {
                                                    needDoNext = true;
                                                }
                                                if (needDoNext) {
                                                    continue;
                                                }
                                                RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                                tmpRetDetail.actArea = p_req7516.actArea;

                                                tmpRetDetail.actNum = isSubAcct ? tmpEachArr[2] : tmpEachArr[1];
                                                tmpRetDetail.cur = this.convertCurToATS(tmpEachArr[3]);

                                                String tmpRecBank = StringHelper.convertToDBC(tmpEachArr[24]).trim();
                                                tmpRetDetail.recAccBank = tmpRecBank;

                                                boolean jionBkArea7516 = getBankConfig().getValueAsBool("jionBkArea7516");
                                                if (tmpRecBank.contains("中国农业银行") && jionBkArea7516 && StringHelper.hasAnyChar(tmpEachArr[20])) {
                                                    tmpRetDetail.recAccNum = tmpEachArr[20].trim() + tmpEachArr[21].trim();
                                                } else {
                                                    tmpRetDetail.recAccNum = tmpEachArr[21].trim();
                                                }
                                                tmpRetDetail.recAccName = tmpEachArr[23].trim();

                                                if (tmpEachArr[14].startsWith("-")) {
                                                    tmpRetDetail.cdFlag = "1";
                                                    if (tmpEachArr[12].equals("1") || tmpEachArr[12].equals("2")) {
                                                        tmpRetDetail.cdFlag = "2";
                                                    }
                                                } else {
                                                    tmpRetDetail.cdFlag = "2";
                                                    if (tmpEachArr[12].equals("1") || tmpEachArr[12].equals("2")) {
                                                        tmpRetDetail.cdFlag = "1";
                                                    }
                                                }
                                                tmpRetDetail.tranAmt = tmpEachArr[14].replace("-", "");

                                                if (tmpEachArr[4].length() == 8) {
                                                    tmpRetDetail.tranDate = tmpEachArr[4].substring(0, 4) + "-" + tmpEachArr[4].substring(4, 6) + "-" + tmpEachArr[4].substring(6, 8);
                                                } else {
                                                    tmpRetDetail.tranDate = tmpEachArr[4];
                                                }
                                                if (tmpEachArr[6].length() >= 14) {
                                                    tmpRetDetail.tranTime = tmpEachArr[6].substring(0, 4) + "-" + tmpEachArr[6].substring(4, 6) + "-" + tmpEachArr[6].substring(6, 8) + " " + tmpEachArr[6].substring(8, 10) + ":" + tmpEachArr[6].substring(10, 12) + ":" + tmpEachArr[6].substring(12, 14);
                                                } else {
                                                    tmpRetDetail.tranTime = tmpEachArr[6];
                                                }
                                                tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                                tmpRetDetail.postTimestamp = tmpEachArr[6];
                                                tmpRetDetail.accBal = tmpEachArr[15];
                                                tmpRetDetail.billType = tmpEachArr[17];
                                                tmpRetDetail.billNum = tmpEachArr[19];
                                                String tmpAbstr = StringHelper.convertToDBC(tmpEachArr[28]);
                                                tmpRetDetail.usage = "false".equalsIgnoreCase(getBankConfig().getValueAsString("TransUsageConvertToDBC")) ? tmpEachArr[28] : tmpAbstr;
                                                if (StringHelper.hasAnyChar(tmpRetDetail.usage) && tmpRetDetail.usage.indexOf(";") > 0) {
                                                    //<Usage>20190423;20190423</Usage>
                                                    String[] spVals = tmpRetDetail.usage.split(";");
                                                    if (spVals.length == 2 && spVals[0].equals(spVals[1])) {
                                                        tmpRetDetail.usage = spVals[0];
                                                    }
                                                }
                                                tmpRetDetail.abstr = pickupAbstr(tmpAbstr);
                                                //tmpRetDetail.comment = tmpEachArr[29];//tmpEachArr[32];
                                                tmpRetDetail.originator = tmpEachArr[5];
                                                tmpRetDetail.payCode = StringHelper.joinNotEmpty("+", tmpEachArr[29], tmpEachArr[31], tmpEachArr[32]);
                                                nodeAnalysic(tmpEachArr, tmpRetDetail, getCharset());
                                                retAts.writeRetDetail(tmpRetDetail);
                                            }
                                        } else {
                                            tmpRespCode = "-1";
                                            tmpRespInfo = tmpSbLog.toString();
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "数据为空";
                                    }
                                }
                            } else if (!"查询无数据!".equals(tmpRetRxtInfo)) {
                                tmpRespCode = "-1";
                                if (!StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                                    tmpRespInfo = tmpRetRxtInfo;
                                } else {
                                    tmpRespInfo = tmpRetInfo;
                                }
                                break;
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpSbMsg.toString();
                            break;
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpStrRet[1];
                        break;
                    }
                }
                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    private RetAtsTrans qrySubAcctTrans(Req7516HisTrans p_req7516) throws Exception {
        //历史明细查询返回ATS的对象
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            ABC02Header bankHeader = new ABC02Header();
            bankHeader.CCTransCode = "CQRD02";//交易代码
            bankHeader.ReqSeqNo = p_req7516.reqHeader.transSeqID;

            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;

            boolean isSubAcct = StringHelper.hasAnyChar(p_req7516.higherLevelAct);
            //按自然月循环查询
            while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //判断是否跨月
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    //跨月则设置为月末
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }


                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                //写入通用的头部节点
                writeCommonHeader(xmlWriter, bankHeader);

                xmlWriter.writeStartElement("Cmp");
                String dbProv = p_req7516.actArea;
                if ("true".equals(getBankConfig().getValueAsString("useActInfoSetOwnerArea").toLowerCase())) {
                    if ((p_req7516.actNum.indexOf('-') > 0 && p_req7516.actNum.length() == 18) || (p_req7516.actNum.length() == 17)) {
                        dbProv = p_req7516.actNum.substring(0, 2);
                    }
                }
                xmlWriter.writeElementString("DbProv", dbProv);
                xmlWriter.writeElementString("DbCur", convertCurToBank(p_req7516.actCur));
                if (!isSubAcct) {
                    xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_req7516.actNum));//借方账号
                    xmlWriter.writeElementString("DbLogAccNo", "0000000000");//起始多级账簿号
                } else {
                    xmlWriter.writeElementString("DbAccNo", getAbcAccNo(p_req7516.higherLevelAct));//借方账号
                    xmlWriter.writeElementString("DbLogAccNo", p_req7516.actNum);//起始多级账簿号
                }
                xmlWriter.writeElementString("StartTime", "0", true);//末笔时间戳
                xmlWriter.writeEndElement();

                xmlWriter.writeStartElement("Corp");
                xmlWriter.writeElementString("StartDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                xmlWriter.writeElementString("EndDate", Format.Date8Format.format(tmpClndrStepTo.getTime()));
                xmlWriter.writeEndElement();


                xmlWriter.writeEndElement();
                xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

                XmlTextReader tmpBkReader;
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                            int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                            if (tmpRecordNum > 0) {
                                String tmpDataMFS = null;
                                String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                                if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                                    String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                    String tmpFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + tmpBatchFileName;
                                    if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                        WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                        DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                        dspClient.charsetName = getCharset();
                                        TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                        if (tcpRec.isCompleted) {
                                            if (tcpRec.isRtnBinaryFile) {
                                                tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                            } else {
                                                String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                                WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                            }
                                        } else {
                                            this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                        }
                                    } else if ("ftp".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        tmpFilePath = getTempFileDirectory() + File.separator + tmpBatchFileName;

                                        WriteBankLogLn2("结果文件保存本机路径: " + tmpFilePath);
                                        FtpSet ftpSet = bankFront.getFtpSet("");
                                        WriteBankLogLn2("ftp服务器待下载文件路径: " + ftpSet.downDir + "/" + tmpBatchFileName);
                                        FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
                                        FtpReceiver ftpReceiver = ftpPortClient.downloadFile(tmpBatchFileName, tmpFilePath);
                                        if (ftpReceiver.isCompleted) {
                                            tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                            WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);
                                        } else {
                                            tmpRespCode = "-1";
                                            tmpRespInfo = "文件下载失败" + ftpReceiver.connMsg;
                                            WriteBankLogLn2("文件下载失败" + ftpReceiver.connMsg);
                                        }
                                    } else {
                                        this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                        tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                    }

                                    if (tmpDataMFS == null) {
                                        this.WriteBankLogLn("读取前置数据文件返回为null，需确认前置文件夹配置和文件是否存在");
                                    } else {
                                        this.WriteBankLogStep3(tmpDataMFS);
                                    }
                                } else {
                                    tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");//
                                }
                                if (tmpDataMFS != null) {
                                    StringBuilder tmpSbLog = new StringBuilder();
                                    ArrayList<String[]> tmpArrayList = MFSHelper.getTextArray(tmpDataMFS, "|", tmpFieldNum, tmpRecordNum, tmpSbLog);
                                    if (tmpSbLog.length() == 0) {
                                        /*
                                        0省市代码|1账号|2账薄号|3货币码|4交易日期|5日志号|6交易时间|7户名|8账薄名|9交易类型|10交易行号|11传票号|12发生额标识|13现转标志|14交易金额|15账户余额|16上笔余额|17凭证种类|18交易码|19凭证号|20对方账号省市代码|21对方账号|22对方账号货币码|23对方账号户名|24对方账号开户行|25错账日期|26错账传票号|27记账柜员|28摘要|29附言|30红蓝字标识|31备注1|32备注2|
										 * */
                                        for (int i = 0; i < tmpArrayList.size(); i++) {
                                            String[] tmpEachArr = tmpArrayList.get(i);
                                            boolean needDoNext = false;
                                            //1.查询账号为多级账簿子账号时，银行返回账号需等于上级账号且银行返回多级账簿号等于查询账号
                                            //2.查询账号为多级账簿主账号时，银行返回账号需等于查询账号且银行返回多级账簿号等于0000000000
                                            if (!((isSubAcct && p_req7516.actNum.equals(tmpEachArr[2]) && getAbcAccNo(p_req7516.higherLevelAct).equals(tmpEachArr[1])) || (!isSubAcct && getAbcAccNo(p_req7516.actNum).equals(tmpEachArr[1]) && "0000000000".equals(tmpEachArr[2])))) {
                                                needDoNext = true;
                                            }
                                            if (needDoNext) {
                                                continue;
                                            }
                                            RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                            tmpRetDetail.actArea = p_req7516.actArea;

                                            tmpRetDetail.actNum = isSubAcct ? tmpEachArr[2] : tmpEachArr[1];
                                            tmpRetDetail.cur = this.convertCurToATS(tmpEachArr[3]);

                                            String tmpRecBank = StringHelper.convertToDBC(tmpEachArr[24]).trim();
                                            tmpRetDetail.recAccBank = tmpRecBank;

                                            boolean jionBkArea7516 = getBankConfig().getValueAsBool("jionBkArea7516");
                                            if (tmpRecBank.contains("中国农业银行") && jionBkArea7516 && StringHelper.hasAnyChar(tmpEachArr[20])) {
                                                tmpRetDetail.recAccNum = tmpEachArr[20].trim() + tmpEachArr[21].trim();
                                            } else {
                                                tmpRetDetail.recAccNum = tmpEachArr[21].trim();
                                            }
                                            tmpRetDetail.recAccName = tmpEachArr[23].trim();

                                            if (tmpEachArr[14].startsWith("-")) {
                                                tmpRetDetail.cdFlag = "1";
                                                if (tmpEachArr[12].equals("1") || tmpEachArr[12].equals("2")) {
                                                    tmpRetDetail.cdFlag = "2";
                                                }
                                            } else {
                                                tmpRetDetail.cdFlag = "2";
                                                if (tmpEachArr[12].equals("1") || tmpEachArr[12].equals("2")) {
                                                    tmpRetDetail.cdFlag = "1";
                                                }
                                            }
                                            tmpRetDetail.tranAmt = tmpEachArr[14].replace("-", "");

                                            if (tmpEachArr[4].length() == 8) {
                                                tmpRetDetail.tranDate = tmpEachArr[4].substring(0, 4) + "-" + tmpEachArr[4].substring(4, 6) + "-" + tmpEachArr[4].substring(6, 8);
                                            } else {
                                                tmpRetDetail.tranDate = tmpEachArr[4];
                                            }
                                            if (tmpEachArr[6].length() >= 14) {
                                                tmpRetDetail.tranTime = tmpEachArr[6].substring(0, 4) + "-" + tmpEachArr[6].substring(4, 6) + "-" + tmpEachArr[6].substring(6, 8) + " " + tmpEachArr[6].substring(8, 10) + ":" + tmpEachArr[6].substring(10, 12) + ":" + tmpEachArr[6].substring(12, 14);
                                            } else {
                                                tmpRetDetail.tranTime = tmpEachArr[6];
                                            }
                                            tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                            tmpRetDetail.postTimestamp = tmpEachArr[6];
                                            tmpRetDetail.accBal = tmpEachArr[15];
                                            tmpRetDetail.billType = tmpEachArr[17];
                                            tmpRetDetail.billNum = tmpEachArr[19];
                                            String tmpAbstr = StringHelper.convertToDBC(tmpEachArr[28]);
                                            tmpRetDetail.usage = "false".equalsIgnoreCase(getBankConfig().getValueAsString("TransUsageConvertToDBC")) ? tmpEachArr[28] : tmpAbstr;
                                            if (StringHelper.hasAnyChar(tmpRetDetail.usage) && tmpRetDetail.usage.indexOf(";") > 0) {
                                                //<Usage>20190423;20190423</Usage>
                                                String[] spVals = tmpRetDetail.usage.split(";");
                                                if (spVals.length == 2 && spVals[0].equals(spVals[1])) {
                                                    tmpRetDetail.usage = spVals[0];
                                                }
                                            }
                                            tmpRetDetail.abstr = pickupAbstr(tmpAbstr);
                                            //tmpRetDetail.comment = tmpEachArr[29];//tmpEachArr[32];
                                            tmpRetDetail.originator = tmpEachArr[5];
                                            tmpRetDetail.payCode = StringHelper.joinNotEmpty("+", tmpEachArr[29], tmpEachArr[31], tmpEachArr[32]);
                                            nodeAnalysic(tmpEachArr, tmpRetDetail, getCharset());
                                            retAts.writeRetDetail(tmpRetDetail);
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = tmpSbLog.toString();
                                    }
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "数据为空";
                                }
                            }
                        } else if (!"查询无数据!".equals(tmpRetRxtInfo)) {
                            tmpRespCode = "-1";
                            if (!StringHelper.isNullOrEmpty(tmpRetRxtInfo)) {
                                tmpRespInfo = tmpRetRxtInfo;
                            } else {
                                tmpRespInfo = tmpRetInfo;
                            }
                            break;
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSbMsg.toString();
                        break;
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                    break;
                }

                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }
}
